import requests
from django.conf import settings
import logging
import json
from datetime import datetime
import time
from django.core.cache import cache
from typing import List
from apps.ai.services.ai_manager import AIManager
from apps.ai.services.ai_service import AIService as BaseAIService
from apps.note.models import NoteHistory, PendingChange
import openai
import re

logger = logging.getLogger('apps')

class AIProcessingError(Exception):
    """AI 处理异常"""
    pass

class RateLimitError(AIProcessingError):
    """请求频率限制错误"""
    pass

class AIService(BaseAIService):
    """扩展基础 AI 服务，提供双功能笔记处理：备忘录与学习笔记"""
    
    def __init__(self):
        super().__init__()
        self.api_key = settings.AI_API_KEY
        self.api_base = settings.AI_API_BASE
        self.config = settings.AI_CONFIG
        self.rate_limit_window = 60  # 频率限制窗口(秒)
        self.max_requests = 50  # 每个窗口最大请求数
        self.ai_manager = AIManager()
        self.context_window = 5
        self.max_history = 50
        self.pending_changes = {}  # 存储待确认的更改
        self.messages = []  # 存储历史消息
        # 初始化 OpenAI 客户端
        self.client = openai.OpenAI(
            api_key=settings.AI_API_KEY,
            base_url=settings.AI_API_BASE
        )

    def _check_rate_limit(self):
        """检查请求频率限制"""
        current_time = int(time.time())
        cache_key = f'ai_request_count_{current_time // self.rate_limit_window}'
        
        # 获取当前窗口的请求计数
        request_count = cache.get(cache_key, 0)
        
        if request_count >= self.max_requests:
            raise RateLimitError("请求过于频繁，请稍后再试")
            
        # 更新请求计数
        cache.set(cache_key, request_count + 1, self.rate_limit_window)

    def _handle_rate_limit(self, retry_after=None):
        """处理频率限制"""
        if retry_after:
            logger.warning(f"触发频率限制，等待 {retry_after} 秒后重试")
            time.sleep(retry_after)
        else:
            # 默认等待时间
            wait_time = self.rate_limit_window - (int(time.time()) % self.rate_limit_window) + 1
            logger.warning(f"触发频率限制，等待 {wait_time} 秒后重试")
            time.sleep(wait_time)

    def _call_api(self, messages, temperature=0.7, max_tokens=1000, **kwargs):
        """调用 AI API"""
        max_retries = 2  # 减少重试次数
        base_wait_time = 0.2  # 减少等待时间
        
        # 添加缓存机制
        cache_key = f"ai_response_{hash(str(messages))}"
        cached_response = cache.get(cache_key)
        if cached_response:
            return cached_response
        
        for retry in range(max_retries):
            try:
                headers = {
                    'Authorization': f'Bearer {self.api_key}',
                    'Content-Type': 'application/json'
                }
                
                data = {
                    'model': self.config['model'],
                    'messages': messages,
                    'temperature': temperature,
                    'max_tokens': max_tokens,
                    **kwargs
                }
                
                logger.info(f"Calling AI API with data: {data}")
                
                api_url = f'{self.api_base}/chat/completions'
                
                try:
                    proxies = settings.AI_PROXY if self.config.get('use_proxy') else None
                    
                    response = requests.post(
                        api_url,
                        headers=headers,
                        json=data,
                        timeout=self.config['timeout'],
                        proxies=proxies,
                        verify=False
                    )
                    
                    if response.status_code == 429:
                        wait_time = base_wait_time * (2 ** retry) + 1  # 增加等待时间
                        logger.warning(f"Rate limit reached, waiting {wait_time} seconds before retry {retry + 1}")
                        time.sleep(wait_time)
                        continue
                    
                    response.raise_for_status()
                    result = response.json()
                    
                    if not result.get('choices') or not result['choices'][0].get('message'):
                        raise AIProcessingError("AI返回格式错误")
                        
                    # 成功后缓存结果
                    if result['choices'][0]['message']['content']:
                        cache.set(cache_key, result['choices'][0]['message']['content'], 3600)  # 缓存1小时
                    
                    return result['choices'][0]['message']['content']
                    
                except requests.exceptions.RequestException as e:
                    wait_time = base_wait_time * (2 ** retry) + 1
                    if retry < max_retries - 1:
                        logger.warning(f"Request failed, retrying in {wait_time} seconds: {str(e)}")
                        time.sleep(wait_time)
                        continue
                    raise AIProcessingError(f"API请求失败: {str(e)}")
                    
            except Exception as e:
                if retry < max_retries - 1:
                    wait_time = base_wait_time * (2 ** retry) + 1
                    logger.warning(f"API error, retrying in {wait_time} seconds: {str(e)}")
                    time.sleep(wait_time)
                    continue
                raise AIProcessingError(f"AI服务错误: {str(e)}")
                
        raise AIProcessingError(f"达到最大重试次数({max_retries})后仍然失败")

    def _call_api_streaming(self, messages, temperature=0.7, max_tokens=1000, **kwargs):
        """流式调用 AI API"""
        try:
            # 检查频率限制
            self._check_rate_limit()
            
            # 构建请求数据
            data = {
                'model': self.config['model'],
                'messages': messages,
                'temperature': temperature,
                'max_tokens': max_tokens,
                'stream': True,  # 启用流式输出
                **kwargs
            }
            
            logger.info(f"调用流式 AI API: {data}")
            
            # 使用 OpenAI 客户端进行流式请求
            response = self.client.chat.completions.create(
                model=self.config['model'],
                messages=messages,
                temperature=temperature,
                max_tokens=max_tokens,
                stream=True
            )
            
            # 返回流式响应对象
            return response
            
        except RateLimitError as e:
            logger.warning(f"触发频率限制: {str(e)}")
            self._handle_rate_limit()
            raise
        except Exception as e:
            logger.error(f"流式 API 调用失败: {str(e)}")
            raise AIProcessingError(f"流式 API 调用失败: {str(e)}")

    def process_note(self, note):
        """处理笔记
        
        Args:
            note: 笔记对象
            
        Returns:
            dict: 处理结果字典
        """
        try:
            results = {}
            
            # 串行处理每个功能，并在每次API调用之间添加延迟
            
            # 1. 生成摘要
            if self.config['features']['summary']:
                try:
                    summary = self.generate_summary(note.content)
                    results['summary'] = summary
                    time.sleep(2)  # 添加延迟，避免频率限制
                except Exception as e:
                    logger.error(f"生成摘要失败: {str(e)}")
                    results['summary'] = {'error': str(e)}

            # 2. 提取关键词 (如果摘要成功，直接使用摘要中的关键词)
            if self.config['features']['keywords']:
                try:
                    if results.get('summary') and not isinstance(results['summary'], dict):
                        keywords = results['summary'].get('keywords', [])
                    else:
                        time.sleep(2)  # 添加延迟
                        keywords = self._extract_keywords(note.content)
                    results['keywords'] = keywords
                except Exception as e:
                    logger.error(f"提取关键词失败: {str(e)}")
                    results['keywords'] = []

            # 3. 生成建议
            if self.config['features']['suggestions']:
                try:
                    time.sleep(2)  # 添加延迟
                    suggestions = self.generate_suggestions(note.content)
                    results['suggestions'] = suggestions
                except Exception as e:
                    logger.error(f"生成建议失败: {str(e)}")
                    results['suggestions'] = {'error': str(e)}

            # 4. 分析内容 (如果前面的处理都成功，可以跳过完整分析)
            if (not results.get('summary') or not results.get('keywords') or 
                not results.get('suggestions')):
                try:
                    time.sleep(2)  # 添加延迟
                    analysis = self.analyze_note(note.content)
                    results['analysis'] = analysis
                except Exception as e:
                    logger.error(f"分析内容失败: {str(e)}")
                    results['analysis'] = {'error': str(e)}

            # 5. 更新笔记状态
            note.ai_processing_status = 'completed'
            note.last_ai_process_time = datetime.now()
            
            # 更新笔记内容
            if results.get('summary') and isinstance(results['summary'], dict):
                note.ai_summary = results['summary'].get('summary', '')
            if results.get('keywords'):
                note.ai_keywords = results['keywords']
            if results.get('suggestions') and isinstance(results['suggestions'], dict):
                note.ai_suggestions = results['suggestions']
            
            note.save()

            return results

        except Exception as e:
            logger.error(f"笔记处理失败: {str(e)}")
            raise AIProcessingError(f"笔记处理失败: {str(e)}")

    def _extract_keywords(self, text: str, max_keywords: int = 10) -> List[str]:
        """提取文本关键词
        
        Args:
            text (str): 需要提取关键词的文本
            max_keywords (int, optional): 最大关键词数量. 默认为 10
            
        Returns:
            List[str]: 关键词列表
        """
        try:
            messages = [
                {
                    'role': 'system',
                    'content': f"""你是一个专业的文本分析助手。请从以下文本中提取最多{max_keywords}个关键词，
                    以JSON数组格式返回，格式如下：
                    ["关键词1", "关键词2", "关键词3"]
                    
                    要求：
                    1. 关键词应该反映文本的主要内容和主题
                    2. 每个关键词长度不超过10个字符
                    3. 按重要性排序
                    4. 不要包含重复或相似的关键词"""
                },
                {
                    'role': 'user',
                    'content': text
                }
            ]
            
            response = self._call_api(messages, temperature=0.3)
            
            # 清理响应文本
            response = response.strip()
            if response.startswith('```json'):
                response = response[7:]
            if response.endswith('```'):
                response = response[:-3]
            response = response.strip()
            
            try:
                keywords = json.loads(response)
                if isinstance(keywords, list):
                    # 确保返回的是字符串列表
                    keywords = [str(k).strip() for k in keywords if k]
                    # 去重
                    keywords = list(dict.fromkeys(keywords))
                    # 限制数量
                    return keywords[:max_keywords]
                else:
                    logger.warning(f"关键词提取返回了非列表结果: {response}")
                    return []
                    
            except json.JSONDecodeError as e:
                logger.error(f"关键词JSON解析失败: {str(e)}, 原始响应: {response}")
                return []
                
        except Exception as e:
            logger.error(f"提取关键词失败: {str(e)}")
            return []

    def generate_summary(self, text: str, type: str = 'concise', language: str = 'zh') -> dict:
        """生成文本摘要
        
        Args:
            text (str): 需要总结的文本内容
            type (str): 摘要类型，可选值：concise/detailed/structured
            language (str): 语言，可选值：zh/en
            
        Returns:
            dict: 包含摘要和关键词的字典
        """
        try:
            # 构建提示词
            if type == 'concise':
                prompt = f"请简洁总结以下文本的主要内容：\n\n{text}"
            elif type == 'detailed':
                prompt = f"请详细总结以下文本的内容，包含主要观点和细节：\n\n{text}"
            else:  # structured
                prompt = f"请以结构化的方式总结以下文本，包含主题和要点：\n\n{text}"

            # 调用AI接口生成摘要
            response = self._call_api(
                messages=[
                    {
                        'role': 'system',
                        'content': '你是一个专业的文本摘要助手。'
                    },
                    {
                        'role': 'user',
                        'content': prompt
                    }
                ],
                temperature=0.7
            )

            # 提取关键词
            keywords = self._extract_keywords(text)

            return {
                'summary': response.strip(),
                'keywords': keywords,
                'type': type,
                'language': language,
                'generated_at': datetime.now().isoformat()
            }

        except Exception as e:
            logger.error(f"生成摘要失败: {str(e)}")
            raise AIProcessingError(f"生成摘要失败: {str(e)}")

    def generate_suggestions(self, text):
        """生成建议"""
        messages = [
            {
                'role': 'system',
                'content': '请分析内容并提供改进建议，包括：结构优化、内容补充、时间管理等方面。'
            },
            {
                'role': 'user',
                'content': f'请分析以下内容并提供建议：\n\n{text}'
            }
        ]
        response = self._call_api(messages)
        return json.loads(response) if isinstance(response, str) else response

    def extract_keywords(self, text):
        """提取关键词"""
        messages = [
            {
                'role': 'system',
                'content': '请提取文本中的关键词，以 JSON 数组形式返回。'
            },
            {
                'role': 'user',
                'content': f'请从以下文本中提取关键词：\n\n{text}'
            }
        ]
        response = self._call_api(messages, temperature=0.3)
        return json.loads(response) if isinstance(response, str) else response

    def chat_streaming(self, message: str, note, resume_from=0):
        """流式对话方法，支持多轮对话和断线重连
        
        Args:
            message: 用户消息
            note: 笔记对象
            resume_from: 从哪个索引位置恢复输出，用于断线重连
            
        Returns:
            Generator: 生成流式响应的生成器
        """
        try:
            import time
            # 流量控制 - 限制API调用频率
            current_time = time.time()
            cache_key = f'chat_streaming_rate_limit_{int(current_time // 60)}'
            request_count = cache.get(cache_key, 0)
            
            if request_count >= 10:  # 每分钟最多10次请求
                logger.warning(f"流式对话请求频率限制: 每分钟最多10次请求, 当前已有{request_count}次")
                yield {
                    "chunk": "请求频率过高，请稍后再试。",
                    "scene": "error",
                    "needs_edit": False
                }
                return
                
            # 更新请求计数
            cache.set(cache_key, request_count + 1, 60)
            
            # 记录开始时间(用于性能监控)
            start_time = time.time()
            
            # 获取笔记上下文
            note_context = {
                'title': note.title,
                'content': note.content,
                'type': note.note_type,
                'status': note.status
            }
            
            # 分析意图和场景
            intent_analysis = self._analyze_intent(message, note_context)
            
            # 构建系统提示词
            system_prompt = self._build_system_prompt(
                intent_analysis['needs_edit'],
                note_context,
                intent_analysis['scene']
            )
            
            # 构建上下文消息
            context_message = self._build_context_message(
                message,
                note_context,
                intent_analysis
            )
            
            # 构建消息列表，包含历史消息
            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": context_message}
            ]
            
            # 添加历史消息（最近的8条，4轮对话）
            if len(self.messages) > 0:
                # 过滤掉系统消息，只保留用户和助手的对话
                history_messages = [msg for msg in self.messages[-8:] if msg.get('role') in ['user', 'assistant']]
                messages.extend(history_messages)
            
            # 添加当前用户消息
            messages.append({"role": "user", "content": message})
            
            # 根据场景调整参数
            temperature = 0.3 if intent_analysis['needs_edit'] else 0.7
            
            # 记录流式API调用开始时间
            api_call_start = time.time()
            
            # 调用流式 API
            try:
                stream_response = self._call_api_streaming(
                    messages=messages,
                    temperature=temperature,
                    max_tokens=2000
                )
                
                # 记录API响应时间
                api_response_time = time.time() - api_call_start
                logger.info(f"流式API响应时间: {api_response_time:.2f}秒")
                
                # 处理流式响应
                full_response = ""
                chunk_index = 0
                token_count = 0
                failed_chunks = 0
                buffer_time = 0
                
                for chunk in stream_response:
                    # 跳过已处理的块（用于断线重连）
                    if chunk_index < resume_from:
                        chunk_index += 1
                        continue
                    
                    # 限制处理速度，避免客户端接收过快
                    if buffer_time > 0:
                        time.sleep(buffer_time)
                    
                    if chunk.choices and hasattr(chunk.choices[0], 'delta') and hasattr(chunk.choices[0].delta, 'content') and chunk.choices[0].delta.content:
                        content = chunk.choices[0].delta.content
                        
                        # 增加错误恢复能力
                        try:
                            # 累积完整响应
                            full_response += content
                            token_count += len(content.split())
                            
                            # 返回每个块及其元数据
                            yield {
                                "chunk": content,
                                "scene": intent_analysis['scene'],
                                "needs_edit": intent_analysis['needs_edit'],
                                "chunk_index": chunk_index,
                                "token_count": token_count
                            }
                            
                            # 更新块索引
                            chunk_index += 1
                            
                        except Exception as chunk_error:
                            # 记录块处理错误但继续处理
                            logger.warning(f"处理响应块时出错: {str(chunk_error)}")
                            failed_chunks += 1
                            # 如果失败太多次，中断处理
                            if failed_chunks > 5:
                                raise Exception(f"处理响应块失败次数过多: {failed_chunks}次")
                
                # 将完整响应添加到历史消息中
                self.messages.append({
                    "role": "user", 
                    "content": message
                })
                
                self.messages.append({
                    "role": "assistant", 
                    "content": full_response
                })
                
                # 限制历史消息数量
                if len(self.messages) > self.max_history:
                    self.messages = self.messages[-self.max_history:]
                
                # 记录性能指标
                total_time = time.time() - start_time
                tokens_per_second = token_count / total_time if total_time > 0 else 0
                logger.info(f"流式对话完成，总时间: {total_time:.2f}秒, 总token: {token_count}, 速率: {tokens_per_second:.1f} tokens/秒")
                
            except Exception as api_error:
                logger.error(f"流式API调用失败: {str(api_error)}")
                # 返回错误信息
                yield {
                    "chunk": f"与AI服务通信时出现错误: {str(api_error)}",
                    "scene": "error",
                    "needs_edit": False,
                    "recoverable": True  # 表示这是可恢复的错误
                }
                # 通过不抛出异常，允许外部重试
        
        except Exception as e:
            logger.error(f"流式对话失败: {str(e)}")
            yield {
                "chunk": f"处理您的请求时出现了问题: {str(e)}",
                "scene": "error",
                "needs_edit": False,
                "recoverable": False  # 表示这是不可恢复的错误
            }

    def chat(self, message: str, note) -> dict:
        """支持多轮对话"""
        try:
            # 获取笔记上下文
            note_context = {
                'title': note.title,
                'content': note.content,
                'type': note.note_type,
                'status': note.status
            }
            
            # 分析意图和场景
            intent_analysis = self._analyze_intent(message, note_context)
            
            # 构建系统提示词
            system_prompt = self._build_system_prompt(
                intent_analysis['needs_edit'],
                note_context,
                intent_analysis['scene']
            )
            
            # 构建上下文消息
            context_message = self._build_context_message(
                message,
                note_context,
                intent_analysis
            )
            
            # 构建消息列表，包含历史消息
            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": context_message}
            ]
            
            # 添加历史消息（最近的8条，4轮对话）
            if len(self.messages) > 0:
                # 过滤掉系统消息，只保留用户和助手的对话
                history_messages = [msg for msg in self.messages[-8:] if msg.get('role') in ['user', 'assistant']]
                messages.extend(history_messages)
            
            # 添加当前用户消息
            messages.append({"role": "user", "content": message})
            
            # 根据场景调整参数
            temperature = 0.3 if intent_analysis['needs_edit'] else 0.7
            
            # 调用AI
            completion = self.client.chat.completions.create(
                model=self.config['model'],
                messages=messages,
                temperature=temperature,
                max_tokens=2000
            )

            # 获取AI回复
            assistant_message = completion.choices[0].message
            
            # 将用户消息和AI回复添加到历史消息中
            self.messages.append({
                "role": "user", 
                "content": message
            })
            
            self.messages.append({
                "role": "assistant", 
                "content": assistant_message.content
            })
            
            # 限制历史消息数量
            if len(self.messages) > self.max_history:
                self.messages = self.messages[-self.max_history:]
            
            # 处理回复内容
            return self._format_response(
                assistant_message.content,
                intent_analysis['scene'],
                intent_analysis['needs_edit']
            )

        except Exception as e:
            logger.error(f"AI对话失败: {str(e)}")
            raise AIProcessingError(f"AI对话失败: {str(e)}")

    def _analyze_intent(self, message: str, note_context: dict) -> dict:
        """分析用户意图和场景
        
        Args:
            message: 用户消息
            note_context: 笔记上下文
            
        Returns:
            dict: 意图分析结果
        """
        # 基础问题和帮助关键词
        help_keywords = [
            '你是谁', '您是谁', '你能做什么', '您能做什么', '帮助', '使用说明',
            '功能介绍', '怎么用', '使用方法', '介绍一下', '介绍自己'
        ]
        
        # 问候关键词
        greeting_keywords = [
            '你好', '您好', '早上好', '中午好', '下午好', '晚上好', 
            '嗨', 'hi', 'hello', '哈喽', '嘿', '在吗', '在么'
        ]
        
        # 编辑意图关键词（按场景分类）
        edit_keywords = {
            'study_plan': [
                '学习计划', '学习安排', '复习计划', '考试计划', '学习规划',
                '学习', '复习', '考试', '课程', '预习', '备考',
                '作业', '论文', '实验', '报告', '笔记', '总结'
            ],
            'task_breakdown': [
                '任务分解', '任务拆分', '任务规划', '项目计划', '工作安排',
                '任务', '项目', '计划', '安排', '进度', '日程',
                '时间', '工作', '活动', '会议', '提醒'
            ],
            'note_enrich': [
                '笔记补充', '内容丰富', '知识扩充', '完善笔记', '充实笔记',
                '补充', '丰富', '完善', '充实', '补全', '填充',
                '知识点', '核心概念', '考点', '重点', '完整性'
            ],
            'note_expand': [
                '知识点扩展', '深度解析', '概念分析', '深入理解', '拓展知识',
                '扩展', '深度', '解析', '分析', '拓展', '探究',
                '详细', '全面', '深入', '实例', '应用场景'
            ],
            'note_optimization': [
                '笔记优化', '内容优化', '笔记改进', '内容修改', '笔记整理',
                '修改', '优化', '改进', '整理', '完善', '重写',
                '调整', '更新', '补充', '添加', '删除', '替换'
            ],
            'content_analysis': [
                '内容分析', '笔记分析', '内容建议', '笔记建议', '内容评价',
                '分析', '建议', '意见', '如何', '怎么', '帮我',
                '能否', '可以', '想要', '需要', '麻烦'
            ]
        }
        
        # 检查是否是问候语
        if any(kw in message.lower() for kw in greeting_keywords):
            return {
                'scene': 'greeting',
                'needs_edit': False,
                'confidence': 1.0
            }
        
        # 检查是否是基础问题
        if any(kw in message.lower() for kw in help_keywords):
            return {
                'scene': 'help',
                'needs_edit': False,
                'confidence': 1.0
            }
        
        # 计算每个场景的置信度
        scene_confidence = {}
        for scene, keywords in edit_keywords.items():
            # 消息中的关键词匹配
            message_matches = sum(1 for kw in keywords if kw in message.lower())
            # 笔记内容中的关键词匹配
            content_matches = sum(1 for kw in keywords if kw in note_context.get('content', '').lower())
            # 计算基础置信度（消息匹配权重更高）
            base_confidence = (message_matches * 0.7 + content_matches * 0.3) / len(keywords)
            scene_confidence[scene] = base_confidence
        
        # 获取最高置信度的场景
        max_scene = max(scene_confidence.items(), key=lambda x: x[1]) if scene_confidence else ('general', 0)
        detected_scene, confidence = max_scene
        
        # 判断是否需要编辑（降低阈值，更容易触发编辑建议）
        needs_edit = confidence > 0.1 or any(
            kw in message.lower() for kw in [
                '这个', '那个', '帮我', '请', '能', '可以',
                '想', '要', '改', '写', '看', '查', '做'
            ]
        )
        
        # 如果消息长度超过10个字符，也认为可能需要编辑
        if len(message.strip()) > 10:
            needs_edit = True
        
        # 如果笔记内容为空，不建议编辑
        if not note_context.get('content'):
            needs_edit = False
        
        return {
            'scene': detected_scene if needs_edit else 'general',
            'needs_edit': needs_edit,
            'confidence': confidence
        }

    def _build_system_prompt(self, is_content_edit: bool, note_context: dict, scene: str) -> str:
        """构建系统角色提示词"""
        user = note_context.get('user', {})
        note_info = note_context.get('note', {})
        note_type = note_info.get('note_type', 'general')
        
        # 获取用户角色和学科领域
        role = user.get('role', 'student')
        subject_area = note_info.get('subject_area', '')
        
        # 检测学科领域（如果未提供）
        if not subject_area and note_info.get('title'):
            from ..services.fine_tuning_service import fine_tuning_service
            detected_subject = fine_tuning_service._detect_subject_area(
                note_info.get('content', ''), 
                note_info.get('title', '')
            )
            if detected_subject:
                subject_area = detected_subject
                logger.info(f"基于标题和内容推断学科领域: {subject_area}")
        
        # 获取专业视角
        if subject_area:
            from ..services.fine_tuning_service import fine_tuning_service
            subject_expertise = fine_tuning_service._get_subject_expertise(subject_area)
        else:
            subject_expertise = "专业学习助手"
        
        # 基础系统提示词
        base_prompt = f"""你是PlanMaster智能AI助手，PlanMaster是一款专为大学生量身打造的智能化记录工具，创新性地将笔记与备忘录功能融为一体，全面提升大学生的学习与生活管理效率。

输出规范要求：
1. 保留原始笔记的所有内容和结构，绝不删除或替换原有内容
2. 只在用户明确要求的部分进行扩充和补充
3. 扩充内容与原文风格一致，保持自然连贯的过渡
4. 直接输出笔记内容，不要添加任何引言、总结或对话式语句
5. 不要使用"对于大学生来说"、"建议通过"等表述
6. 不要在内容结尾添加"希望对你有帮助"等总结语
7. 不要有"基于你提供的笔记"等这种表达
8. 输出的内容是完整的笔记、备忘或者任务计划
9. 确保新增内容与原内容有明显关联，而不是脱离原内容的新话题
10.除了正常的笔记内容之外，不要添加任何多余的介绍性语句
"""
        
        # 场景特定提示词
        scene_prompts = {
            'note_chat': f"""作为{subject_expertise}，你主要任务是帮助用户补充、完善、拓展和解释其笔记内容。用户向你提问时，先理解笔记内容和上下文，然后提供专业、准确的回答。

请遵循以下指导原则：
1. 以用户笔记内容为核心，所有回答必须与笔记主题紧密相关
2. 使用符合大学水平的专业表达，既学术准确又便于理解
3. 对知识点进行系统性拓展，提供深入的理论基础和应用场景
4. 在解释复杂概念时，适当使用类比和例子增强理解
5. 回答问题时保持简洁和重点突出，避免冗长陈述
6. 当用户要求修改笔记内容时，提供完整、结构化的修改版本

特别注意：
- 对于理工科内容，确保公式和推导步骤准确，使用专业术语
- 对于人文社科内容，注重多角度分析和批判性思考的培养
- 当笔记内容明显不完整或有错误时，主动提出建议和改进方案
- 针对学术专业相关内容，提供最新研究视角和学术规范建议
""",
            
            'note_optimization': f"""作为{subject_expertise}，你的任务是帮助优化用户的笔记内容，提高其教育价值和学习效果。

请遵循以下指导原则：
1. 保留原始笔记的核心内容和结构，在此基础上进行改进
2. 增强笔记的逻辑性和连贯性，确保知识点之间的关联清晰
3. 补充必要的定义、解释和例子，使概念更加清晰
4. 添加对重要概念的深入讲解，展示其在学科中的位置
5. 改进笔记的层次结构，使用适当的标题和小标题组织内容
6. 确保所有专业术语都有适当的解释和上下文
7. 调整语言表达，使其更加简洁、精确和专业

特别注意：
- 必须保留所有原笔记内容，只进行补充和完善，不删除原内容
- 对于{subject_area or "专业"}内容，特别注重专业准确性和学术规范
- 确保最终内容符合大学教育水平，既有深度又便于理解
- 保持回应的教育价值和实用性，避免泛泛而谈
- 当用户要求详细解释特定部分时，只对该部分进行扩充，其他部分保持原样
""",
            
            'study_plan': f"""作为学习规划专家，你的任务是帮助大学生创建有效的学习计划。基于用户的笔记内容和请求，制定结构化的学习路径。

请遵循以下指导原则：
1. 分析用户笔记中的知识点，确定学习重点和难点
2. 设计循序渐进的学习步骤，从基础概念到高级应用
3. 为每个学习阶段设定明确的目标和时间框架
4. 推荐有效的学习方法和资源，包括阅读材料、练习和复习策略
5. 考虑不同学习风格，提供多样化的学习活动
6. 包含定期的自我评估和测试环节，帮助巩固所学内容
7. 设计灵活的计划，允许用户根据实际情况进行调整

特别注意：
- 计划必须具体、可行，避免过于宽泛或无法实施的建议
- 考虑用户作为大学生的时间限制和其他课程负担
- 针对{subject_area or "相关学科"}的特点，定制专业的学习策略
- 强调深度理解而非机械记忆，培养批判性思维和问题解决能力
- 包含应对考试和实际应用的准备建议
""",
            
            'task_breakdown': f"""作为任务分解专家，你的任务是帮助大学生将复杂的学习任务分解为可管理的步骤。

请遵循以下指导原则：
1. 全面分析用户的学习任务，识别主要组成部分和挑战
2. 将任务分解为有逻辑顺序的小步骤，确保每一步清晰可行
3. 估计每个步骤所需的时间和资源，帮助用户进行规划
4. 明确每个步骤的具体目标和完成标准
5. 提供执行每个步骤的具体方法和技巧
6. 设计检查点，让用户能够评估进度并进行必要的调整
7. 考虑可能的障碍和解决方案，提前做好应对准备

特别注意：
- 分解后的步骤应具体、清晰、可操作
- 考虑任务的整体目标和学习成果
- 针对{subject_area or "学科"}特点，提供专业的任务分解策略
- 强调关键步骤和潜在的难点，提供相应的支持建议
- 平衡任务的完整性和可管理性，避免过于细碎或过于笼统
""",
            
            'help': """PlanMaster智能学习助手，可以帮助大学生完成以下任务：

1. 笔记内容咨询：解答与笔记相关的问题，解释概念和理论
2. 笔记优化：完善和拓展笔记内容，提高学术质量和实用性
3. 制定学习计划：基于笔记内容创建结构化的学习路径和时间表
4. 任务分解：将复杂的学习任务分解为可管理的步骤
5. 知识拓展：提供与笔记主题相关的扩展知识和最新研究
6. 解题指导：分析问题并提供解题思路和方法

你可以这样向我提问：
- "解释一下这个笔记中的[概念]"
- "帮我完善这份笔记，使其更加全面"
- "设计一个学习计划，帮我掌握这些知识点"
- "将这个项目任务分解为具体步骤"
- "提供一些关于[主题]的额外资源和阅读材料"
- "这个公式/理论有什么实际应用？"

我会基于你的笔记内容和需求，提供专业、准确、有针对性的帮助。""",
            
            'greeting': """作为PlanMaster智能学习助手，我专注于帮助大学生提升学习效果和笔记质量。

我能为你提供以下服务：
- 回答与笔记内容相关的问题
- 优化和完善你的笔记内容
- 根据笔记创建个性化学习计划
- 将复杂学习任务分解为可管理步骤
- 提供知识扩展和深度解析

你可以直接向我提问，或使用以下指令：
- 解释：请求对笔记中概念的解释
- 优化：要求改进笔记内容
- 计划：请求制定学习计划
- 分解：将任务分解为步骤

请告诉我你需要什么样的帮助，我会根据你的笔记内容提供专业支持。"""
        }
        
        # 选择合适的场景提示词
        if is_content_edit:
            scene_prompt = scene_prompts.get('note_optimization', scene_prompts['note_chat'])
        else:
            scene_prompt = scene_prompts.get(scene, scene_prompts['note_chat'])
        
        # 添加针对特定笔记类型的指导
        note_type_guidance = ""
        if note_type == 'study' and subject_area:
            note_type_guidance = f"""
当前笔记是关于{subject_area}的学习笔记。请特别注重学术准确性、知识结构化和考试重点标识。针对大学课程学习需求，提供系统化的知识解析和学习建议。
"""
        elif note_type == 'task':
            note_type_guidance = """
当前笔记是任务或项目记录。请注重任务分解、时间规划和执行步骤的清晰性。提供项目管理的专业建议和效率提升策略。
"""
        elif note_type == 'meeting':
            note_type_guidance = """
当前笔记是会议记录。请帮助提炼关键信息、明确行动项和后续步骤。提供信息组织和要点总结的专业建议。
"""
        
        # 组合最终的提示词
        final_prompt = f"{base_prompt}\n\n{scene_prompt}\n{note_type_guidance}"
        
        return final_prompt

    def _build_context_message(self, message: str, note_context: dict, intent_analysis: dict) -> str:
        """根据不同场景构建上下文消息
        
        Args:
            message: 用户消息
            note_context: 笔记上下文
            intent_analysis: 意图分析结果
            
        Returns:
            str: 上下文消息
        """
        scene = intent_analysis.get('scene', 'general')
        
        # 如果笔记内容存在，构建基础上下文
        base_content = ""
        if note_context.get('content'):
            base_content = f"""当前笔记内容：
{note_context['content']}

请基于以上内容，"""
        
        # 根据场景构建不同的提示词
        prompts = {
            'study_plan': f"""{base_content}帮我制定或优化学习计划。要求：
1. 结合当前学习内容和进度
2. 合理分配学习时间，避免疲劳
3. 设置明确的学习目标和检查点
4. 包含具体的学习方法和建议
5. 注意休息时间的安排
6. 考虑大学生的学习特点和时间安排""",

            'note_enrich': f"""{base_content}帮我补充和丰富笔记内容。要求：
1. 确保概念表述准确完整
2. 补充缺失的知识点和背景信息
3. 使用⭐标记考试常见考点和易错点
4. 保持专业性和学术准确性
5. 使用标准Markdown语法格式化内容
6. 适合大学生学习和复习使用""",

            'note_expand': f"""{base_content}帮我深度扩展和解析重要概念。要求：
1. 对重要概念进行多维度分析
2. 提供理论的发展脉络和应用背景
3. 添加实际应用案例和具体场景
4. 分析概念之间的关联和区别
5. 提供深层次的理解框架
6. 使用标准Markdown语法呈现""",

            'note_optimization': f"""{base_content}帮我优化笔记内容。要求：
1. 保持原有的核心内容
2. 改进内容的组织结构
3. 突出重点和关键概念
4. 添加必要的解释或例子
5. 使内容更清晰易懂
6. 适合大学生复习和记忆""",

            'task_breakdown': f"""{base_content}帮我将任务分解为可管理的步骤。要求：
1. 基于现有任务进行分解
2. 任务分解要具体可执行
3. 合理安排优先级
4. 添加时间节点
5. 考虑大学生的时间特点
6. 提供执行建议""",

            'help': f"""请介绍一下PlanMaster智能助手的功能和使用方法。作为一款面向大学生的多功能智能化笔记工具，请详细说明您能提供哪些帮助。""",
            
            'greeting': f"""请以PlanMaster智能助手的身份友好地回应用户的问候，并简要介绍您可以提供的服务。""",
            
            'general': f"""{base_content if base_content else ''}分析并回答我的问题，提供对大学生有帮助的建议和信息。"""
        }
        
        # 返回对应场景的提示词，如果没有匹配则返回通用提示
        return prompts.get(scene, f"{base_content if base_content else ''}分析并回答我的问题。")

    def _format_response(self, response_text, scene='note_chat', is_editing=False):
        """
        格式化AI响应，适配前端预期格式
        
        Args:
            response_text: AI的响应文本
            scene: 交互场景
            is_editing: 是否为内容编辑请求
            
        Returns:
            dict: 格式化后的响应对象
        """
        # 默认响应类型为普通消息
        response_type = 'message'
        
        # 检查是否包含特定问候语标记
        greeting_keywords = ['你好', '您好', 'hello', 'hi', '嗨', '哈喽', '早上好', '下午好', '晚上好']
        is_greeting = any(keyword in response_text.lower() for keyword in greeting_keywords)
        if is_greeting:
            # 如果包含问候语，标记为问候类型
            response_type = 'greeting'
        
        # 检查是否为编辑场景或是否包含内容修改建议
        is_edit_content = scene == 'note_optimization' or is_editing or self._contains_edit_keywords(response_text)
        
        logger.info(f"格式化响应: scene={scene}, is_editing={is_editing}, is_edit_content={is_edit_content}")
        
        if is_edit_content:
            # 设置为编辑建议类型
            response_type = 'edit_suggestion'
            
            # 尝试从响应中提取建议内容
            suggested_content = self._extract_suggested_content_from_text(response_text)
            
            # 生成友好的AI回复说明，描述修改了什么内容
            ai_explanation = self._generate_edit_explanation(response_text, suggested_content)
            
            logger.info(f"编辑响应: ai_explanation={ai_explanation[:50]}..., suggested_content_length={len(suggested_content) if suggested_content else 0}")
            
            # 构建带有明确分离的内容和回复的响应
            return {
                'complete_content': response_text,
                'type': response_type,
                'scene': scene,
                'edit_content': True,
                'suggestedContent': suggested_content or response_text,
                'ai_response': ai_explanation,
                'is_edit': True,
                # 关键字段：分离内容和回复
                'contentOnly': suggested_content or response_text,  # 仅包含内容部分，用于编辑器
                'responseOnly': ai_explanation  # 仅包含回复部分，用于对话气泡
            }
        
        # 普通对话场景的响应
        return {
            'complete_content': response_text,
            'type': response_type,
            'scene': scene
        }
        
    def _generate_edit_explanation(self, full_response, suggested_content):
        """
        生成友好的编辑说明，描述所做的修改
        
        Args:
            full_response: 完整的AI响应
            suggested_content: 提取出的建议内容
            
        Returns:
            str: 友好的编辑说明
        """
        # 默认说明
        default_explanation = "我已根据您的要求修改了内容，您可以在编辑区域查看完整内容。"
        
        try:
            # 检查是否有明确的修改说明部分
            explanation_markers = [
                "我已", "我做了", "已完成", "已更新", "已修改", "我帮您", "我为您", 
                "修改包括", "主要修改", "变更如下", "更新了以下"
            ]
            
            # 如果没有提取到内容，直接返回默认说明
            if not suggested_content:
                return default_explanation
                
            # 从完整响应中提取说明部分
            for marker in explanation_markers:
                if marker in full_response:
                    # 寻找句子或段落，包含说明而非内容
                    sentences = full_response.split('。')
                    for sentence in sentences:
                        if marker in sentence and len(sentence) < 200:  # 说明通常较短
                            if sentence.strip().endswith('：') or sentence.strip().endswith(':'):
                                return sentence.strip() + " 请查看编辑区域的完整内容。"
                            return sentence.strip() + "。 请查看编辑区域的完整内容。"
            
            # 没有找到特定的说明，返回默认说明
            return default_explanation
            
        except Exception as e:
            logger.error(f"生成编辑说明失败: {str(e)}")
            return default_explanation

    def _contains_edit_keywords(self, text):
        """检查文本是否包含编辑建议的关键词"""
        edit_keywords = [
            '修改', '编辑', '更新', '优化', '改进', '调整', '替换', '重写',
            '建议修改', '可以改为', '应该改为', '更好的写法', '建议内容'
        ]
        return any(keyword in text for keyword in edit_keywords)

    def _extract_suggested_content_from_text(self, text):
        """
        从AI响应文本中智能提取建议内容
        
        Args:
            text: AI响应文本
            
        Returns:
            str: 提取的建议内容
        """
        if not text:
            return ""
            
        logger.info(f"从文本中提取建议内容，文本长度: {len(text)}")
        
        # 检查文本是否已经是良好格式化的内容
        # 如果文本以Markdown标题开始，并且包含至少两个段落，可能已经是格式良好的内容
        if text.strip().startswith('#') and '\n\n' in text[:500]:
            logger.info("检测到文本以Markdown标题开始，可能是格式化内容")
            # 尝试清理可能的结尾说明文字
            ending_explanations = [
                "希望这对你有所帮助",
                "希望这些内容对你有用",
                "如果你有任何问题",
                "如有任何疑问",
                "祝你学习愉快"
            ]
            cleaned_text = text
            for ending in ending_explanations:
                if ending in cleaned_text:
                    ending_pos = cleaned_text.find(ending)
                    if ending_pos > len(cleaned_text) * 0.8:  # 如果出现在文本后部分
                        cleaned_text = cleaned_text[:ending_pos].strip()
            return cleaned_text
            
        # 首先尝试使用常见的分隔符模式
        content_patterns = [
            # Markdown代码块包裹的内容
            r'```(?:markdown)?\s*([\s\S]+?)\s*```',
            # 以"以下是内容"等开头的段落
            r'(?:以下是|这是|修改后的内容|优化后的内容|更新后的内容|修改如下|建议内容如下|修改版本如下)[：:]\s*([\s\S]+)',
            # 引用块内的内容
            r'>\s*([\s\S]+?)(?:\n\n|\Z)',
            # 分隔线后的内容
            r'(?:\n-{3,}|\n={3,}|\n\*{3,})\s*\n([\s\S]+)',
            # 以"原始内容"和"修改内容"标记的区域
            r'(?:修改(?:后|建议)的(?:内容|版本))[：:]\s*([\s\S]+?)(?:(?:\n\n)|\Z)',
            # 标记明确的内容部分
            r'<content>([\s\S]+?)</content>',
        ]
        
        import re
        for pattern in content_patterns:
            matches = re.findall(pattern, text, re.DOTALL)
            if matches:
                # 返回第一个匹配结果
                content = matches[0].strip()
                logger.info(f"使用模式 '{pattern}' 匹配到内容, 长度: {len(content)}")
                
                # 进一步清理内容，移除可能存在的解释段落
                lines = content.split('\n')
                if len(lines) > 3:
                    # 检查前几行是否为解释性文本
                    explanation_lines = 0
                    for i in range(min(3, len(lines))):
                        if lines[i].strip() and (
                            lines[i].endswith('：') or 
                            lines[i].endswith(':') or
                            lines[i].strip() in ['修改内容如下', '建议内容如下', '以下是修改内容']
                        ):
                            explanation_lines = i + 1
                            # 如果下一行为空行，也跳过
                            if explanation_lines < len(lines) and not lines[explanation_lines].strip():
                                explanation_lines += 1
                    
                    if explanation_lines > 0:
                        content = '\n'.join(lines[explanation_lines:])
                
                # 检查是否有标题，如果没有但原始文本有，尝试提取并添加
                if not content.strip().startswith('#') and text.strip().startswith('#'):
                    # 提取原始文本的标题
                    title_match = re.match(r'^(#+\s+[^\n]+\n)', text.strip())
                    if title_match:
                        title = title_match.group(1)
                        logger.info(f"从原始文本提取到标题: {title.strip()}")
                        content = title + content
                
                return content.strip()
        
        # 如果没有明确的标记，检查是否有编辑说明
        lines = text.split('\n')
        content_start = 0
        
        # 寻找可能的编辑说明结束位置
        for i, line in enumerate(lines):
            if i > 5:  # 不检查超过前5行
                break
            if ':' in line or '：' in line or line.endswith('。') or line.endswith('.'):
                content_start = i + 1
                # 如果遇到空行，认为说明已结束
                if content_start < len(lines) and not lines[content_start].strip():
                    content_start += 1
        
        if content_start > 0 and content_start < len(lines):
            # 检查是否需要保留标题
            if content_start > 1 and lines[0].strip().startswith('#'):
                logger.info(f"在提取的内容前保留原始标题: {lines[0].strip()}")
                # 如果内容不包含标题，但第一行是标题，保留它
                return lines[0] + '\n' + '\n'.join(lines[content_start:]).strip()
            return '\n'.join(lines[content_start:]).strip()
        
        # 智能检测Markdown格式
        # 寻找第一个Markdown标题或列表项
        content_start = 0
        for i, line in enumerate(lines):
            line_stripped = line.strip()
            if line_stripped.startswith('#') or line_stripped.startswith('-') or line_stripped.startswith('*') or re.match(r'^\d+\.', line_stripped):
                content_start = i
                break
        
        if content_start > 0:
            # 再次检查是否需要保留标题
            if content_start > 1 and lines[0].strip().startswith('#'):
                # 如果找到的内容不是以标题开始，但原始文本第一行是标题
                if not lines[content_start].strip().startswith('#'):
                    logger.info(f"在提取的Markdown内容前保留原始标题: {lines[0].strip()}")
                    return lines[0] + '\n' + '\n'.join(lines[content_start:]).strip()
            return '\n'.join(lines[content_start:]).strip()
        
        # 如果以上方法都无法提取内容，尝试移除可能的前导解释文本
        # 通常AI会在修改建议前添加一些说明文字
        explanation_limit = min(len(text) // 3, 200)  # 取文本前1/3或前200个字符作为可能的说明
        if len(text) > explanation_limit * 3:  # 确保文本足够长
            # 查找可能的分隔标记
            for delimiter in ['\n\n', '\n---', '\n===', '\n***', '\n\r\n']:
                split_pos = text.find(delimiter, explanation_limit // 2, explanation_limit * 2)
                if split_pos > 0:
                    # 检查分隔前是否有标题需要保留
                    if text[:split_pos].strip().startswith('#'):
                        title_match = re.match(r'^(#+\s+[^\n]+\n)', text.strip())
                        if title_match:
                            title = title_match.group(1)
                            logger.info(f"从分隔前的文本提取到标题: {title.strip()}")
                            return title + text[split_pos + len(delimiter):].strip()
                    return text[split_pos + len(delimiter):].strip()
        
        # 如果无法识别特定模式，返回原始文本，但添加日志警告
        logger.warning(f"无法从文本中提取结构化内容，返回原始文本, 长度: {len(text)}")
        return text

    def _clean_suggested_content(self, content: str) -> str:
        """清理建议内容中的元数据"""
        # 移除标题、类型、状态等元数据行
        lines = content.split('\n')
        cleaned_lines = []
        skip_patterns = ['标题：', '类型：', '状态：', '内容：']
        
        for line in lines:
            if not any(pattern in line for pattern in skip_patterns):
                cleaned_lines.append(line)
        
        # 移除开头的空行
        while cleaned_lines and not cleaned_lines[0].strip():
            cleaned_lines.pop(0)
        
        return '\n'.join(cleaned_lines)

    def _detect_scene(self, message: str, content: str) -> str:
        """检测对话场景"""
        # 保持原有的场景检测逻辑
        if any(keyword in message for keyword in ['计划', '安排', '日程']):
            return 'plan'
        elif any(keyword in message for keyword in ['优化', '改进', '修改']):
            return 'optimization'
        elif any(keyword in message for keyword in ['建议', '意见', '如何']):
            return 'suggestion'
        return 'message'

    def process_chat(self, message, note_content, note_type):
        """处理 AI 对话请求"""
        try:
            if not message:
                raise ValueError("消息不能为空")

            try:
                logger.info(f"Processing chat message: {message}")
                
                # 调用 AI 接口
                response = self._call_api(
                    messages=[
                        {
                            "role": "system",
                            "content": "你是一个专业的学习助手，请根据用户的需求提供专业的帮助。"
                        },
                        {
                            "role": "user",
                            "content": f"""基于以下内容回复：
笔记内容：{note_content or '无'}
笔记类型：{note_type or 'general'}
用户消息：{message}
"""
                        }
                    ],
                    temperature=0.7
                )
                
                logger.info(f"Raw AI response: {response}")

                # 提取响应内容
                response_text = None
                if isinstance(response, str):
                    response_text = response
                elif isinstance(response, dict):
                    response_text = response.get('content') or response.get('message', str(response))
                elif hasattr(response, 'choices') and response.choices:
                    response_text = response.choices[0].message.content
                else:
                    response_text = str(response)

                if not response_text:
                    raise ValueError("AI 响应内容为空")

                logger.info(f"Processed response text: {response_text}")

                # 返回成功响应，简化数据结构
                return {
                    'status': 'success',
                    'message': '操作成功',
                    'data': {
                        'response': response_text,
                        'type': 'message'
                    }
                }

            except Exception as api_error:
                logger.error(f"AI API 调用失败: {str(api_error)}")
                raise ValueError(f"AI 服务异常: {str(api_error)}")

        except ValueError as ve:
            logger.warning(f"AI 处理参数错误: {str(ve)}")
            return {
                'status': 'error',
                'message': str(ve)
            }
        except Exception as e:
            logger.error(f"AI 处理失败: {str(e)}")
            return {
                'status': 'error',
                'message': '处理失败，请稍后重试'
            }

    def _generate_study_plan(self, message, content):
        """生成学习计划"""
        return {
            'type': 'study_plan',
            'content': {
                'overview': '这是一个为你定制的学习计划',
                'schedule': [
                    {
                        'phase': '第一阶段',
                        'duration': '3天',
                        'focus': '基础知识巩固',
                        'tasks': [
                            '复习基本概念',
                            '做基础练习题'
                        ]
                    }
                ],
                'tips': [
                    '建议每天复习2-3小时',
                    '注意休息间隔'
                ]
            },
            'display': {
                'title': '📚 学习计划',
                'color': '#64b5f6'
            }
        }

    def _optimize_content(self, message, content):
        """优化内容"""
        return {
            'type': 'content_optimization',
            'content': {
                'original': content,
                'optimized': '优化后的内容...',
                'changes': [
                    '改进了结构',
                    '突出了重点'
                ]
            },
            'display': {
                'title': '✨ 内容优化',
                'color': '#4caf50'
            }
        }

    def _breakdown_task(self, message, content):
        """任务分解"""
        return {
            'type': 'task_breakdown',
            'content': {
                'main_task': '主要任务',
                'subtasks': [
                    {
                        'title': '子任务1',
                        'duration': '2小时',
                        'priority': 'high'
                    }
                ]
            },
            'display': {
                'title': '📋 任务分解',
                'color': '#ff9800'
            }
        }

    def _handle_general_chat(self, message: str, note) -> dict:
        """处理普通对话请求"""
        try:
            # 检查是否是生成内容的请求
            if self._is_content_generation_request(message):
                # 生成内容建议
                suggested_content = self._generate_content_suggestion(message, note)
                
                # 存储待确认的更改
                self._set_pending_change(note.id, {
                    'content': suggested_content,
                    'old_content': note.content,
                    'timestamp': time.time()
                })
                
                return {
                    'type': 'edit_suggestion',
                    'content': f"根据您的要求，我生成了以下内容：\n\n{suggested_content}\n\n您可以确认应用这些更改，或者告诉我需要进一步修改的地方。",
                    'suggestions': ['确认应用', '继续修改', '放弃修改']
                }
            
            # 检查是否是确认应用更改的消息
            if self._is_confirmation_message(message):
                return self._handle_confirmation(message, note)
            
            # 调用 AI 接口
            response = self._call_api(
                messages=[
                    {
                        "role": "system",
                        "content": """我正在开发一个大学生服务外包竞赛项目：一款适合大学生的计划型的AI备忘录app：面向大学生的多功能智能化备忘录工具。 为了帮助大学生更好的处理学习、生活和工作中的问题，提高工作效率，你是一个专业的学习、生活和工作的多功能智能助手，专为大学生设计。你的主要职责是：

现在是处理普通对话请求的模式,请按照以下方式回答问题：
1. 帮助用户优化笔记内容，使其更加结构化和易于理解
2. 根据用户需求制定详细的学习、生活和工作计划和时间安排
3. 将复杂任务分解为可管理的步骤
4. 提供学习、生活和工作方法和效率提升的建议
5. 回答用户关于学习、生活和工作和时间管理的问题

当前笔记内容：{note.content or '无内容'}
笔记类型：{note.note_type or 'general'}
字数限制：5000字

请注意：
- 当用户请求修改或优化笔记内容时，提供具体的修改建议
- 当用户确认修改时，明确告知用户修改已应用
- 保持友好、专业的语气，鼓励用户提高学习效率
- 提供具体、可行的建议，避免泛泛而谈
- 如果用户表示满意或确认，询问是否要应用更改
"""
                    },
                    {
                        "role": "user",
                        "content": message
                    }
                ],
                temperature=0.7,
                max_tokens=1000
            )
            
            # 处理响应
            if isinstance(response, dict) and 'content' in response:
                content = response['content']
            elif isinstance(response, str):
                content = response
            else:
                content = "抱歉，我无法理解您的请求。"
            
            # 生成建议
            suggestions = self._generate_suggestions(message, note)
            
            return {
                'type': 'message',
                'content': content,
                'suggestions': suggestions
            }
            
        except Exception as e:
            logger.error(f"处理普通对话失败: {str(e)}")
            return {
                'type': 'message',
                'content': f"抱歉，处理您的请求时出现了问题: {str(e)}",
                'suggestions': []
            }

    def _is_confirmation_message(self, message: str) -> bool:
        """检查是否是确认应用更改的消息"""
        confirmation_keywords = [
            '确认', '应用', '接受', '采纳', '同意', '好的', '可以', 
            '没问题', '就这样', '确定', '是的', '对', '行', 'ok', 'yes'
        ]
        
        message = message.lower()
        return any(keyword in message for keyword in confirmation_keywords)

    def _contains_content_suggestion(self, message: str, response: str) -> bool:
        """检查是否包含内容修改建议"""
        suggestion_indicators = [
            '建议修改', '可以改为', '优化为', '调整为', '修改为',
            '建议将', '可以将', '应该将', '不如改成', '更好的表达是'
        ]
        
        # 检查用户消息是否请求修改
        modification_request = any(keyword in message.lower() for keyword in [
            '修改', '优化', '改进', '调整', '重写', '润色', '完善'
        ])
        
        # 检查回复是否包含修改建议
        has_suggestion = any(indicator in response for indicator in suggestion_indicators)
        
        return modification_request and has_suggestion

    def _extract_suggested_content(self, response: str, original_content: str) -> str:
        """从回复中提取建议的内容"""
        try:
            # 尝试提取完整的建议内容
            content_markers = [
                ('建议修改为：\n', '\n\n'),
                ('优化后的内容：\n', '\n\n'),
                ('修改后的内容：\n', '\n\n'),
                ('调整后的内容：\n', '\n\n'),
                ('以下是修改后的内容：\n', '\n\n')
            ]
            
            for start_marker, end_marker in content_markers:
                if start_marker in response:
                    start_idx = response.find(start_marker) + len(start_marker)
                    if end_marker in response[start_idx:]:
                        end_idx = response.find(end_marker, start_idx)
                        if end_idx > start_idx:
                            return response[start_idx:end_idx].strip()
                    else:
                        # 如果没有找到结束标记，取到末尾
                        return response[start_idx:].strip()
            
            # 如果没有明确的标记，尝试智能分析
            # 这里可以添加更复杂的内容提取逻辑
            
            return None
        except Exception as e:
            logger.error(f"提取建议内容失败: {str(e)}")
            return None

    def _generate_dynamic_suggestions(self, message: str, response: str) -> list:
        """生成动态建议按钮"""
        suggestions = []
        
        # 根据用户消息和AI回复生成相关建议
        if '计划' in message or '安排' in message:
            suggestions.extend(['查看完整计划', '调整计划时间', '添加提醒'])
        
        if '学习' in message or '复习' in message:
            suggestions.extend(['制定学习计划', '分解学习任务', '推荐学习方法'])
        
        if '任务' in message or '工作' in message:
            suggestions.extend(['分解任务', '设置优先级', '估计完成时间'])
        
        # 限制建议数量
        if len(suggestions) > 3:
            suggestions = suggestions[:3]
        
        # 如果没有生成建议，添加默认建议
        if not suggestions:
            suggestions = ['继续优化', '制定计划', '提供建议']
        
        return suggestions

    def _detect_intent(self, message: str) -> str:
        """检测用户意图
        
        Args:
            message: 用户消息
            
        Returns:
            str: 意图类型
        """
        # 意图关键词映射
        intent_keywords = {
            'study_plan': ['学习计划', '复习计划', '考试计划', '学习安排', '复习安排', 
                          '计划', '安排', '规划', '学习', '复习'],
            'note_optimization': ['优化', '改进', '修改', '完善', '调整', '建议',
                                '润色', '重写', '整理'],
            'task_breakdown': ['分解', '拆分', '细化', '步骤', '任务', '子任务',
                             '如何开始', '怎么做'],
            'summary': ['总结', '概括', '归纳', '要点', '重点', '摘要'],
            'confirmation': ['确认', '好的', '可以', '同意', '就这样', 'ok', '对',
                           '是的', '没问题', '行']
        }
        
        # 转换消息为小写以便匹配
        message = message.lower()
        
        # 检查每个意图的关键词
        for intent, keywords in intent_keywords.items():
            if any(keyword in message for keyword in keywords):
                logger.info(f"检测到意图: {intent}, 消息: {message}")
                return intent
        
        # 默认返回普通对话意图
        return 'general_chat'

    def _handle_study_plan(self, message: str, note) -> dict:
        """处理学习计划请求"""
        try:
            response = self.ai_manager.generate_study_plan(
                content=note.content,
                message=message
            )
            
            return {
                'type': 'study_plan',
                'content': response.get('content', ''),
                'suggestions': []
            }
        except Exception as e:
            logger.error(f"生成学习计划失败: {str(e)}")
            raise

    def _handle_note_optimization(self, message: str, note) -> dict:
        """处理笔记优化请求"""
        try:
            response = self.ai_manager.optimize_note(
                content=note.content,
                message=message
            )
            
            return {
                'type': 'note_optimization',
                'content': response.get('content', ''),
                'suggestions': []
            }
        except Exception as e:
            logger.error(f"优化笔记失败: {str(e)}")
            raise

    def _handle_task_breakdown(self, message: str, note) -> dict:
        """处理任务分解请求"""
        try:
            response = self.ai_manager.analyze_task(
                content=note.content,
                message=message
            )
            
            return {
                'type': 'task_breakdown',
                'content': response.get('content', ''),
                'suggestions': []
            }
        except Exception as e:
            logger.error(f"分解任务失败: {str(e)}")
            raise

    def _handle_confirmation(self, message: str, note) -> dict:
        """处理确认请求"""
        try:
            # 获取待确认的更改
            pending_change = self._get_pending_change(note.id)
            
            if not pending_change:
                logger.warning(f"没有找到待确认的更改: note_id={note.id}")
                return {
                    'type': 'message',
                    'content': '没有待确认的更改，请先让我为您生成内容建议。',
                    'suggestions': ['优化笔记内容', '制定学习计划', '分解学习任务']
                }
            
            logger.info(f"应用待确认的更改: note_id={note.id}, 原内容长度={len(note.content)}, 新内容长度={len(pending_change.get('content', ''))}")
            
            # 应用更改
            note.content = pending_change.get('content', note.content)
            note.save()
            
            # 记录历史
            NoteHistory.objects.create(
                note=note,
                change_type='ai_update',
                old_content=pending_change.get('old_content', ''),
                new_content=note.content
            )
            
            # 清除待确认的更改
            self._clear_pending_change(note.id)
            
            return {
                'type': 'success',
                'content': '已成功更新笔记内容。还有其他需要帮助的吗？',
                'suggestions': ['查看更新后的内容', '继续优化', '制定学习计划']
            }
            
        except Exception as e:
            logger.error(f"处理确认失败: {str(e)}")
            raise

    def _get_pending_change(self, note_id: int) -> dict:
        """获取待确认的更改
        
        Args:
            note_id: 笔记ID
            
        Returns:
            dict: 待确认的更改
        """
        try:
            # 使用数据库存储待确认的更改
            pending_change = PendingChange.objects.filter(note_id=note_id).order_by('-created_at').first()
            
            if pending_change:
                return {
                    'content': pending_change.content,
                    'old_content': pending_change.old_content,
                    'timestamp': pending_change.created_at.timestamp()
                }
            
            return {}
            
        except Exception as e:
            logger.error(f"获取待确认更改失败: {str(e)}")
            return {}
            
    def _clear_pending_change(self, note_id: int):
        """清除待确认的更改
        
        Args:
            note_id: 笔记ID
        """
        try:
            PendingChange.objects.filter(note_id=note_id).delete()
            
        except Exception as e:
            logger.error(f"清除待确认更改失败: {str(e)}")
            
    def _set_pending_change(self, note_id: int, change: dict):
        """设置待确认的更改
        
        Args:
            note_id: 笔记ID
            change: 更改内容
        """
        try:
            # 清除之前的待确认更改
            self._clear_pending_change(note_id)
            
            # 创建新的待确认更改
            PendingChange.objects.create(
                note_id=note_id,
                content=change.get('content', ''),
                old_content=change.get('old_content', '')
            )
            
        except Exception as e:
            logger.error(f"设置待确认更改失败: {str(e)}")

    def _is_content_generation_request(self, message: str) -> bool:
        """检查是否是内容生成请求
        
        Args:
            message: 用户消息
            
        Returns:
            bool: 是否是内容生成请求
        """
        # 内容生成关键词
        generation_keywords = [
            '生成', '创建', '写', '帮我写', '制作', '编写', 
            '优化', '改进', '修改', '重写', '润色', '完善',
            '整理', '调整', '更新', '替换', '改写'
        ]
        
        # 检查消息是否包含内容生成关键词
        message = message.lower()
        logger.info(f"检查是否是内容生成请求: message={message}")
        result = any(keyword in message for keyword in generation_keywords)
        logger.info(f"内容生成请求检查结果: {result}")
        return result

    def _generate_content_suggestion(self, message: str, note) -> str:
        """生成内容建议
        
        Args:
            message: 用户消息
            note: 笔记对象
            
        Returns:
            str: 建议的内容
        """
        try:
            # 构建提示词
            prompt = f"""
            请根据以下要求，生成或优化笔记内容：
            
            原始内容：
            {note.content or '无内容'}
            
            用户要求：
            {message}
            
            请生成完整的优化后内容，保持结构清晰，内容丰富。
            """
            
            # 调用AI接口
            response = self._call_api(
                messages=[
                    {
                        "role": "system",
                        "content": "你是一个专业的内容优化助手，擅长根据用户需求优化和生成高质量的笔记内容。"
                    },
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                temperature=0.7,
                max_tokens=2000
            )
            
            # 处理响应
            if isinstance(response, dict) and 'content' in response:
                return response['content']
            elif isinstance(response, str):
                return response
            else:
                return "无法生成有效的内容建议。"
            
        except Exception as e:
            logger.error(f"生成内容建议失败: {str(e)}")
            return "生成内容建议时出现错误，请稍后重试。"

    def _generate_suggestions(self, message: str, note) -> List[str]:
        """根据消息和笔记内容生成建议选项
        
        Args:
            message: 用户消息
            note: 笔记对象
            
        Returns:
            List[str]: 建议选项列表
        """
        try:
            # 基础建议选项
            base_suggestions = [
                "优化笔记内容",
                "制定学习计划",
                "分解学习任务"
            ]
            
            # 根据笔记类型添加特定建议
            if note.note_type == 'task':
                base_suggestions.append("如何提高完成效率")
            elif note.note_type == 'study':
                base_suggestions.append("推荐学习资源")
            elif note.note_type == 'plan':
                base_suggestions.append("调整计划时间")
            
            # 根据消息内容添加上下文相关建议
            if '考试' in message or '复习' in message:
                base_suggestions.append("制定考试复习计划")
            elif '论文' in message or '写作' in message:
                base_suggestions.append("论文写作建议")
            elif '时间' in message or '效率' in message:
                base_suggestions.append("时间管理技巧")
            
            # 限制建议数量
            return base_suggestions[:4]
            
        except Exception as e:
            logger.error(f"生成建议选项失败: {str(e)}")
            return ["优化笔记内容", "制定学习计划", "分解学习任务"]

    def process_voice_input(self, voice_data) -> str:
        """处理语音输入"""
        # 假设有一个函数将语音转换为文本
        text = self.convert_voice_to_text(voice_data)
        return text

    def process_image_input(self, image_data) -> str:
        """处理图像输入"""
        # 假设有一个函数将图像中的文本提取出来
        text = self.extract_text_from_image(image_data)
        return text

    def generate_personalized_recommendations(self, user_id) -> list:
        """生成个性化推荐"""
        # 根据用户的历史记录生成推荐
        recommendations = []
        # 假设有一个函数获取用户的历史记录
        history = self.get_user_history(user_id)

        # 根据历史记录生成推荐
        for item in history:
            recommendations.append(f"基于您之前的学习，建议您关注 {item.title}。")

        return recommendations

    def auto_summarize(self, content: str) -> str:
        """自动生成摘要"""
        messages = [
            {
                'role': 'system',
                'content': '请为以下内容生成简洁的摘要。'
            },
            {
                'role': 'user',
                'content': content
            }
        ]
        response = self._call_api(messages)
        return response.get('content', '')

    def _is_content_edit_request(self, message: str) -> bool:
        """判断是否是内容修改相关的请求"""
        edit_keywords = [
            # 学习计划相关
            '学习计划', '复习计划', '考试准备', '课程安排', '学习方法',
            
            # 任务计划相关
            '任务计划', '项目计划', '活动安排', '日程安排',
            
            # 笔记优化相关
            '笔记优化', '笔记整理', '知识点总结', '重点整理',
            
            # 时间管理相关
            '时间管理', '日程规划', '效率提升',
            
            # 职业规划相关
            '职业规划', '实习', '求职', '简历',
            
            # 生活计划相关
            '生活计划', '作息安排', '健康管理', '运动计划',
            
            # 内容处理相关
            '修改', '优化', '改进', '重写', '完善', '生成',
            '总结', '归纳', '提炼', '概括', '整理', '完善',
            '补充', '展开', '拓展', '补全', '扩展', '更新',
            '增加', '添加', '扩充', '详细',
            
            # 建议相关
            '建议', '意见', '如何', '怎么样'
        ]
        
        # 记录调试信息
        logger.info(f"检查内容编辑请求: {message}")
        
        # 检查消息中是否包含任何关键词
        for keyword in edit_keywords:
            if keyword in message:
                logger.info(f"检测到编辑关键词: {keyword}")
                return True
                
        return False

    def optimize_content(self, content: str) -> str:
        """优化笔记内容
        
        Args:
            content: 原始内容
            
        Returns:
            str: 优化后的内容
        """
        try:
            if not content or len(content.strip()) < 10:
                return ""
            
            messages = [
                {
                    "role": "system",
                    "content": """你是一个专业的内容优化助手。请优化用户提供的笔记内容，使其更加清晰、结构化和易于理解。
                    要求：
                    1. 保持原始内容的核心信息和意图
                    2. 改进内容的结构和组织
                    3. 修正语法和表达错误
                    4. 使内容更加连贯和易读
                    5. 如果是计划类内容，确保时间安排合理
                    6. 如果是学习笔记，确保重点突出
                    7. 如果是会议记录，确保要点清晰
                    8. 直接返回优化后的内容，不要包含任何解释或其他内容"""
                },
                {
                    "role": "user",
                    "content": f"请优化以下笔记内容：\n\n{content}"
                }
            ]
            
            # 调用AI服务
            optimized_content = self._call_api(messages, temperature=0.3, max_tokens=2000)
            
            return optimized_content.strip()
            
        except Exception as e:
            logger.error(f"优化内容失败: {str(e)}")
            return ""

    def generate_plan(self, content: str) -> str:
        """根据内容生成计划
        
        Args:
            content: 笔记内容
            
        Returns:
            str: 生成的计划
        """
        try:
            if not content or len(content.strip()) < 10:
                return ""
            
            messages = [
                {
                    "role": "system",
                    "content": """你是一个专业的计划制定助手。请根据用户提供的内容，生成一个详细、可执行的计划。
                    要求：
                    1. 计划应该具体、清晰、可执行
                    2. 包含时间安排和步骤
                    3. 考虑优先级和依赖关系
                    4. 如果内容中已有计划框架，请优化并完善它
                    5. 直接返回计划内容，不要包含任何解释或其他内容"""
                },
                {
                    "role": "user",
                    "content": f"请根据以下内容生成一个详细的计划：\n\n{content}"
                }
            ]
            
            # 调用AI服务，使用默认的 max_tokens 值
            plan = self._call_api(messages, temperature=0.3)
            
            return plan.strip()
            
        except Exception as e:
            logger.error(f"生成计划失败: {str(e)}")
            return ""

    def _try_parse_json(self, text):
        """尝试从文本中解析JSON"""
        try:
            # 查找JSON开始和结束的位置
            if '{' in text and '}' in text:
                start = text.find('{')
                end = text.rfind('}') + 1
                json_str = text[start:end]
                
                # 清理JSON字符串
                json_str = json_str.replace('\n', ' ').replace('\r', ' ')
                json_str = ' '.join(json_str.split())  # 规范化空白字符
                
                # 尝试解析
                return json.loads(json_str)
        except:
            pass
        return None

    def process_study_note(self, message: str, note, task_type='enrich', subject_area=None):
        """
        处理大学学习笔记，提供笔记完善或要点拓展服务
        
        参数:
            message: 用户消息
            note: 笔记对象
            task_type: 处理类型 - enrich(完善笔记) 或 expand(拓展要点)
            subject_area: 学科领域

        返回:
            包含处理结果的字典
        """
        try:
            # 获取笔记内容
            note_content = note.content if hasattr(note, 'content') else str(note)
            note_title = note.title if hasattr(note, 'title') else None

            # 如果没有提供学科领域，尝试检测
            if not subject_area and note_title:
                # 从fine_tuning_service导入检测方法
                from ..services.fine_tuning_service import fine_tuning_service
                detected_subject = fine_tuning_service._detect_subject_area(note_content, note_title)
                if detected_subject:
                    subject_area = detected_subject
                    logger.info(f"基于标题 '{note_title}' 推断学科领域: {subject_area}")

            # 使用Fine-tuning服务进行处理
            from ..services.fine_tuning_service import fine_tuning_service

            # 首次尝试使用微调服务
            try:
                logger.info(f"开始处理学习笔记，任务类型: {task_type}, 学科: {subject_area or '未指定'}")

                # 构建选项字典
                options = {
                    'note_title': note_title,
                    'subject_area': subject_area
                }

                # 使用微调服务处理笔记
                result_generator = fine_tuning_service.optimize_note(
                    note_content,
                    task_type=task_type,
                    subject_area=subject_area,
                    stream=True,
                    note_title=note_title
                )

                # 返回流式处理结果
                return {
                    'status': 'success',
                    'type': 'streaming',
                    'generator': result_generator,
                    'task_type': task_type,
                    'subject_area': subject_area or '未指定'
                }

            except Exception as e:
                logger.error(f"微调服务处理失败: {str(e)}")

                # 构建备用提示词
                if task_type == 'enrich':
                    system_prompt = """你是一位专业的大学学习助手，擅长帮助大学生完善笔记内容。请对提供的笔记进行系统化的补充和完善，使其更加全面、准确和有深度。保留原有内容和结构，添加必要的解释、例子、公式和相关知识。确保内容符合大学学术水平，便于理解和记忆。

重要：请直接输出笔记内容，不要添加任何引言、总结或对学生的建议说明。不要使用"对于大学生来说"、"建议通过"等表述。输出内容应该只包含笔记本身，就像是一份完整的学习材料，而不是对话回复。"""
                    user_prompt = f"请完善以下笔记内容，使其更加全面和有深度：\n\n笔记标题：{note_title or '未提供'}\n\n{note_content}"
                else:  # expand
                    system_prompt = """你是一位专业的大学学习助手，擅长基于笔记要点进行知识拓展。请对提供的笔记要点进行系统性的知识拓展和深入讲解，提供详细解释、理论基础和应用场景。使用符合大学水平的专业表达，既学术准确又便于理解。

重要：请直接输出笔记内容，不要添加任何引言、总结或对学生的建议说明。不要使用"对于大学生来说"、"建议通过"等表述。输出内容应该只包含笔记本身，就像是一份完整的学习材料，而不是对话回复。"""
                    user_prompt = f"请基于以下笔记要点进行知识拓展和深入讲解：\n\n笔记标题：{note_title or '未提供'}\n\n{note_content}"

                # 如果有学科领域，添加专业指导
                if subject_area:
                    system_prompt += f"\n\n请以{subject_area}专家的视角，确保内容的专业准确性和教学针对性，同时仍然只输出纯笔记内容，不要有任何建议性语句。"

                # 使用标准API调用作为备选方案
                try:
                    logger.info("使用标准API作为备选方案进行处理")
                    result = self._call_api([
                        {"role": "system", "content": system_prompt},
                        {"role": "user", "content": user_prompt}
                    ], temperature=0.7, max_tokens=3000)

                    # 清理结果，移除可能的对话性质的文本
                    cleaned_result = self._clean_study_note_output(result)

                    # 处理返回结果
                    return {
                        'status': 'success',
                        'content': cleaned_result,
                        'type': 'message',
                        'task_type': task_type,
                        'subject_area': subject_area or '未指定',
                        'using_fallback': True
                    }
                except Exception as fallback_error:
                    logger.error(f"备用处理方法也失败: {str(fallback_error)}")
                    raise fallback_error

        except Exception as e:
            logger.error(f"处理学习笔记失败: {str(e)}")
            return {
                'status': 'error',
                'message': f"处理笔记时出错: {str(e)}",
                'type': 'error'
            }

    def _clean_study_note_output(self, content):
        """清理学习笔记输出，移除对话性质的文本"""
        if not content:
            return content

        # 移除常见的AI对话式回复模式
        patterns_to_remove = [
            # 开头的对话式回复
            r'^(好的|这是|以下是|下面是|我将|我已经|我帮你|我可以|这里是|为你提供).*?\n',
            r'^(Here is|I have|I will|I can).*?\n',
            # 结尾的建议或总结
            r'\n(希望这对你有所帮助|希望这些信息对你有用|希望这能帮到你|如有任何问题|如果你有任何疑问).*?$',
            r'\n(建议你|你可以|对于大学生来说|通过|值得注意的是).*?$',
            r'\n(I hope|Hope this helps|Let me know|Feel free).*?$',
            # 整段学习建议
            r'\n- \*\*理论学习\*\*：.*?(\n|$)',
            r'\n- \*\*实践应用\*\*：.*?(\n|$)',
            r'\n- \*\*问题诊断\*\*：.*?(\n|$)',
            r'\n-? (理论学习|实践应用|问题诊断)[：:](.*?)(\n|$)',
            # 建议语句段落
            r'\n建议(大学生|学生)在学习这些知识点时.*?$',
            r'\n对于大学生(来说)?，.*?$',
            r'\n在学习过程中，建议.*?$',
            # 其他对话标记
            r'\*\*注意：\*\*.*?\n',
            r'\*\*提示：\*\*.*?\n',
            r'\*\*建议：\*\*.*?\n',
        ]

        cleaned_content = content
        for pattern in patterns_to_remove:
            cleaned_content = re.sub(pattern, '', cleaned_content, flags=re.IGNORECASE | re.MULTILINE)

        # 处理多余的换行
        cleaned_content = re.sub(r'\n{3,}', '\n\n', cleaned_content)

        # 移除开头可能的段落说明
        cleaned_content = re.sub(r'^TCP是.*?协议。\s+', '', cleaned_content, flags=re.DOTALL)

        # 移除最后一段建议性质的内容
        cleaned_content = re.sub(r'\n\n[^\n]+学习[^\n]+建议[^\n]+$', '', cleaned_content, flags=re.MULTILINE)
        cleaned_content = re.sub(r'\n\n在.*?学习.*?中.*?$', '', cleaned_content, flags=re.MULTILINE)

        return cleaned_content.strip()

    def _separate_content_and_comments(self, content):
        """分离笔记内容和AI评论"""
        # 使用正则表达式分离内容和评论
        content_pattern = r'(?<=\n\n)(.*?)(?=\n\n)'
        content_match = re.search(content_pattern, content)
        if content_match:
            content = content_match.group(1)
            ai_comments = content_match.group(0).split('\n\n')[1:]
            return content, ai_comments
        else:
            return content, []

    def _post_process_content(self, content):
        """对生成的内容进行后处理，确保格式正确
        """
        if not content:
            return content
            
        # 修复常见的Markdown语法错误
        # 1. 确保标题前有空行
        content = re.sub(r'([^\n])\n(#{1,6} )', r'\1\n\n\2', content)
        
        # 2. 确保列表项格式正确
        content = re.sub(r'(\n[*\-+]) ([^\n]+)(?!\n)', r'\1 \2\n', content)
        
        # 3. 确保代码块格式正确
        content = re.sub(r'```(\w+)(?!\n)', r'```\1\n', content)
        content = re.sub(r'(?<!\n)```(?!\n)', r'\n```', content)
        
        # 4. 移除多余的空行（超过2个连续空行）
        content = re.sub(r'\n{3,}', '\n\n', content)
        
        # 5. 修复可能的LaTeX格式错误
        content = content.replace('$$\\', '$$\\\\')
        
        return content.strip()
            
    def _analyze_note_content(self, content):
        """分析笔记内容，判断类型和可能的学科领域
        
        Args:
            content: 笔记内容
            
        Returns:
            tuple: (笔记类型, 学科领域)，笔记类型可能是 'study', 'task', 'plan', 'general'
        """
        try:
            # 学习笔记特征关键词
            study_keywords = [
                '概念', '定义', '理论', '公式', '定律', '方程', '模型', '原理',
                '定理', '证明', '推导', '例题', '习题', '解析', '解答', '总结',
                '笔记', '课程', '学习', '复习', '知识点', '教材', '课本', '讲义',
                '章节', '问题', '答案', '论文', '文献', '研究', '实验'
            ]
            
            # 备忘录特征关键词（包含任务和计划关键词）
            memo_keywords = [
                '待办', '记得', '提醒', '备忘', '记录', '安排',
                '任务', '计划', '目标', '截止', '日期', '时间',
                '步骤', '阶段', '进度', '优先级', '紧急', '重要',
                '项目', '活动', '会议', '准备', '负责', '联系',
                '电话', '邮件', '地址', '联系人', '购买', '支付'
            ]
            
            # 学科领域关键词
            subject_keywords = {
                'math': ['数学', '代数', '几何', '微积分', '函数', '方程', '矩阵'],
                'physics': ['物理', '力学', '电磁学', '热学', '光学', '量子'],
                'cs': ['计算机', '算法', '编程', '数据库', '网络', '操作系统'],
                'chemistry': ['化学', '元素', '分子', '化合物', '反应'],
                'biology': ['生物', '细胞', '基因', '生态', '进化'],
                'economics': ['经济', '市场', '金融', '货币', '投资'],
                'literature': ['文学', '小说', '诗歌', '散文', '作家'],
                'history': ['历史', '朝代', '事件', '人物', '战争']
            }
            
            content_lower = content.lower()
            
            # 计算学习笔记和备忘录关键词匹配数
            study_score = sum(1 for kw in study_keywords if kw in content_lower)
            memo_score = sum(1 for kw in memo_keywords if kw in content_lower)
            
            # 判断笔记类型
            # 计算相对比例而非绝对数量
            study_ratio = study_score / len(study_keywords) if study_keywords else 0
            memo_ratio = memo_score / len(memo_keywords) if memo_keywords else 0
            
            # 如果学习笔记特征更明显，判定为学习笔记
            note_type = 'study' if study_ratio > memo_ratio else 'general'
            
            # 只有对学习笔记才进行学科判断
            subject_area = None
            if note_type == 'study':
                # 计算各学科的匹配度
                subject_scores = {}
                for subject, keywords in subject_keywords.items():
                    matches = sum(1 for kw in keywords if kw in content_lower)
                    subject_scores[subject] = matches / len(keywords) if matches > 0 else 0
                
                # 如果有明显的学科特征，确定学科
                max_score = max(subject_scores.values()) if subject_scores else 0
                if max_score > 0.1:  # 设置一个最小阈值
                    subject_area = max(subject_scores.items(), key=lambda x: x[1])[0]
            
            return note_type, subject_area
            
        except Exception as e:
            logger.error(f"分析笔记内容失败: {str(e)}")
            return 'general', None
            
    def _get_subject_expertise(self, subject_area=None):
        """根据学科领域返回相应的专业身份描述
        """
        if not subject_area:
            return "大学学习与笔记整理专家，精通多个学科领域的知识体系和教学方法"
        
        subject_expertise_map = {
            'math': "数学教育专家，精通高等数学、线性代数、概率统计等数学分支的知识体系和教学方法",
            'physics': "物理学教育专家，精通力学、电磁学、热力学、量子力学等物理学分支的知识体系和教学方法",
            'cs': "计算机科学教育专家，精通算法、数据结构、操作系统、数据库等计算机科学领域的知识体系和教学方法",
            'chemistry': "化学教育专家，精通有机化学、无机化学、物理化学等化学分支的知识体系和教学方法",
            'biology': "生物学教育专家，精通细胞生物学、分子生物学、生态学等生物学分支的知识体系和教学方法",
            'economics': "经济学教育专家，精通微观经济学、宏观经济学、计量经济学等经济学分支的知识体系和教学方法",
            'literature': "文学教育专家，精通文学理论、文学史、文本分析等文学研究方法和教学体系",
            'history': "历史学教育专家，精通中外历史、史学方法论、历史文献分析等历史学研究方法和教学体系",
            'philosophy': "哲学教育专家，精通逻辑学、形而上学、伦理学等哲学分支的知识体系和教学方法",
            'psychology': "心理学教育专家，精通认知心理学、发展心理学、社会心理学等心理学分支的知识体系和教学方法",
            'medicine': "医学教育专家，精通解剖学、生理学、病理学等医学基础和临床医学知识体系",
            'law': "法学教育专家，精通法理学、宪法学、民商法学等法学分支的知识体系和教学方法",
            'engineering': "工程教育专家，精通力学、材料学、控制理论等工程基础和专业知识体系",
            'language': "语言学教育专家，精通语音学、语法学、语义学等语言学分支的知识体系和教学方法",
            'database': "数据库系统专家，精通关系数据库理论、SQL查询优化、数据库设计范式、事务处理与并发控制等核心知识"
        }
        
        return subject_expertise_map.get(subject_area, "大学学习与笔记整理专家，精通多个学科领域的知识体系和教学方法")

# 创建全局实例
ai_service = AIService()

# 导出
__all__ = ['ai_service', 'AIService']
